/*!
 Temelia - Stack performance tests.

 Copyright (C) 2008 Ceata (http://cod.ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "include/performance.hpp"
#include "include/testutil.hpp"
#include <stack>

extern "C"
{
#include <temelia/stack.h>
}

// Temelia
static void temelia_stack_push(int n)
{
	stack_t temelia_stack = stack_new(n);
	for (int i = 0; i < n; i++)
		stack_push(temelia_stack, &i);
	stack_delete(temelia_stack);
}

static void temelia_stack_pop(int n)
{
	stack_t temelia_stack = stack_new(n);

	for (int i = 0; i < n; i++)
		stack_push(temelia_stack, &i);

	while (!stack_is_empty(temelia_stack))
		stack_pop(temelia_stack);

	stack_delete(temelia_stack);
}

static void my_temelia_key_handler(void *key, void *context)
{

}

static void temelia_stack_iterate(int n)
{
	stack_t temelia_stack = stack_new(n);

	for (int i = 0; i < n; i++)
		stack_push(temelia_stack, &i);

	stack_iterate(temelia_stack, my_temelia_key_handler, NULL, 1);
	stack_delete(temelia_stack);
}

// STL
static void stl_stack_push(int n)
{
	std::stack<int *> stl_stack;
	for (int i = 0; i < n; i++)
		stl_stack.push(&i);
}

static void stl_stack_pop(int n)
{
	std::stack<int *> stl_stack;

	for (int i = 0; i < n; i++)
		stl_stack.push(&i);

	while (!stl_stack.empty())
		stl_stack.pop();
}

static void my_stl_key_handler(int *key, void *context)
{

}

static void stl_stack_iterate(int n)
{
	std::stack<int*> stl_stack;

	for (int i = 0; i < n; i++)
		stl_stack.push(&i);

	while (!stl_stack.empty())
	{
		my_stl_key_handler(stl_stack.top(), NULL);
		stl_stack.pop();
	}
}

void TemeliaPerformance::pt_stack(void)
{
	TestUnit testUnit("stack");

	GENERATE_TEMELIA_TEST(testUnit, "push", stack_push);
	GENERATE_TEMELIA_TEST(testUnit, "pop", stack_pop);
	GENERATE_TEMELIA_TEST(testUnit, "iterate", stack_iterate);

	GENERATE_STL_TEST(testUnit, "push", stack_push);
	GENERATE_STL_TEST(testUnit, "pop", stack_pop);
	GENERATE_STL_TEST(testUnit, "iterate", stack_iterate);

	testUnit.write(fout);
}
